package com.weike.yuanding.controller;

import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.weike.yuanding.core.domain.R;
import com.weike.yuanding.strategy.ChatStrategy;
import com.weike.yuanding.strategy.ChatStrategyFactory;
import com.weike.yuanding.util.RedisUtil;
import com.weike.yuanding.utils.BaseContext;
import com.weike.yuanding.vo.ChatVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName: ChatController
 * @Author: YuanDing
 * @Date: 2025/4/23 20:26
 * @Description:
 */

@RestController
@RequestMapping("ai")
public class ChatController {

    @Value("${ai.role}")
    public String role;

    @Autowired
    private ChatStrategyFactory chatStrategyFactory;


    private static final String MESSAGE_HISTORY_KEY = "miaoying:ai:chat:";

    /**
     * ai对话
     * @param chatVo
     * @return
     * @throws NoApiKeyException
     * @throws InputRequiredException
     */
    @PostMapping(value = "chat" , produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter chat(@RequestBody ChatVo chatVo) throws NoApiKeyException, InputRequiredException {
        ChatStrategy aiStrategyImpl = chatStrategyFactory.getAiStrategyImpl();
        SseEmitter sseEmitter = new SseEmitter(-1L);

        String currentRedisUserKey = MESSAGE_HISTORY_KEY + BaseContext.userId.get();

        boolean isNew;

        // 如果会话不存在则创建会话id
        if (!RedisUtil.hExists(currentRedisUserKey , chatVo.getSessionId())) {
            chatVo.setSessionId(RedisUtil.hLen(currentRedisUserKey) + "_" +chatVo.getSessionId());
            isNew = true;
        } else {
            isNew = false;
        }

        String sessionId = chatVo.getSessionId();
        // 从redis中取出对话历史
        List<Message> messageList = RedisUtil.hGetList(currentRedisUserKey , sessionId , Message.class);

        if (isNew) {
            messageList.add(
                    Message.builder()
                            .content(role)
                            .role(Role.SYSTEM.getValue())
                            .build()
            );
        }

        if (messageList == null) {
            messageList = new ArrayList<>();
        }
        Message message = new Message();
        message.setRole(Role.USER.getValue());
        message.setContent(chatVo.getQuestion());
        messageList.add(message);
        StringBuffer result = new StringBuffer();
        List<Message> finalMessageList = messageList;
        String finalCurrentRedisUserKey = currentRedisUserKey;
        aiStrategyImpl.execute(messageList ,chatVo , (chatResVo) -> {
            try {
                if (!chatResVo.isDone()) {
                    if (Objects.equals(chatResVo.getType(), "1")) {
                        result.delete(0 , result.capacity());
                        result.append(chatResVo.getContent());
                    }
                    sseEmitter.send(new JSONObject(chatResVo).toString());
                }else {
                    // 如果是新对话返回前端当前的id
                    if (isNew) {
                        chatResVo.setType("8");
                        chatResVo.setContent(chatVo.getSessionId());
                        sseEmitter.send(new JSONObject(chatResVo).toString());
                    }

                    sseEmitter.complete();

                    finalMessageList.add(Message.builder()
                            .content(result.toString())
                            .role(Role.ASSISTANT.getValue())
                            .build());
                    RedisUtil.hSet(finalCurrentRedisUserKey, sessionId , finalMessageList);
                }

            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });
        return sseEmitter;
    }


    /**
     * 获取用户的全部对话列表
     * @return
     */
    @GetMapping("list")
    public R list() {
        String userId = BaseContext.userId.get();
        String currentRedisUserKey = MESSAGE_HISTORY_KEY + userId;
        Map<String, List<Message>> allLists = RedisUtil.hGetAllLists(currentRedisUserKey, Message.class);
        return R.ok(allLists);
    }

    /**
     * 获取会话下的全部历史
     * @return
     */
    @GetMapping("chatList/{id}")
    public R chatList(@PathVariable("id") String id) {
        String userId = BaseContext.userId.get();
        String currentRedisUserKey = MESSAGE_HISTORY_KEY + userId;
        List<Message> messages = RedisUtil.hGetList(currentRedisUserKey, id, Message.class);
        return R.ok(messages);
    }

    /**
     * 删除聊天历史
     * @return
     */
    @GetMapping("del/{id}")
    public R chatDel(@PathVariable("id") String id) {
        String userId = BaseContext.userId.get();
        String currentRedisUserKey = MESSAGE_HISTORY_KEY + userId;

        RedisUtil.hDel(currentRedisUserKey, id);
        return R.ok();
    }

}
